<?php
namespace app\common\controller;
use think\Controller;
use think\Session;
use think\Db;
use think\Cache;
use think\Request;

/**
 * 后台公用基础控制器
 * Class AdminBase
 * @package app\common\controller
 */
class AdminBase extends Controller {

    public $role_list =array();
    public $menu_list =array();
    public $user_level =array();

    protected function _initialize() {
        parent::_initialize();
        
        if (!Session::get('admin_info'))
            //如果COOKIE存在自动登录
            $this->ajaxChkLogin();
        
        //缓存需要的信息
        $this->setCache();
        
        //获取该管理员的权限菜单和拼接可以访问的节点信息存在session中
        $menu_list = $this->getPermissions(explode(',', Session::get('admin_info.role_id')));
        
        //输出权限菜单信息
        if(Session::get('admin_info.is_super') != 1){
            $this->outputMenu($menu_list);
        }else{
            $this->outputMenu($this->admin_menu_list);
        }
        
        //当前访问的节点
        $node = Request::instance()->module().'/'.lcfirst(Request::instance()->controller()).'/'.Request::instance()->action();
        
        //记录行为日志
        $this->actionLog($node);
        
        //不需要验证权限的节点
        $no_node = array(
            'admin/index/index',
            'admin/upload/add'
        );
        
        //判断权限
        if(!in_array($node, $no_node) && !in_array($node, Session::get('node'))){
            if(Session::get('admin_info.is_super') != 1){ //如果不是超级管理员
                if(Request::instance()->isAjax()){
                    die(\UtilD::handleResult(0,'你无权访问！'));
                }else{
                    \UtilD::showError('你无权访问！');
                }
            }
        }
    }
    
    
    /**
     * 自动登录
     */
    public function ajaxChkLogin() {
        // 如果用户没有登录，就直接从cookie中取出用户名密码直接登录
        if (cookie('admin_name') && cookie('admin_password')) {
            $des_key = config('COOKIE_ENCRYPTION');
            $admin_info = array();
            $admin_info['admin_name'] = trim(\UtilD::decrypt(cookie('admin_name'), $des_key));
            $admin_info['admin_password'] = trim(\UtilD::decrypt(cookie('admin_password'), $des_key));
            if(model('Admin')->checkLogin($admin_info) == 3){
                $this->redirect('/admin/Login/index');
            }
        }else{
            $this->redirect('/admin/Login/index');
        }
    }
    
    /**
     * 设置缓存
     */
    private function setCache () {
        
        //角色表信息
        if(!Cache::get('role_list')){
            //获取数据缓存2个小时
            $data = array_reduce(Db::name('Role')->select(),function(&$newArray,$v){$newArray[$v['role_id']] = $v;return $newArray;});
            Cache::set('role_list',$data,config('CACHE_TIME'));
        }
        
        //会员等级
        if(!Cache::get('user_level')){
            //获取数据缓存2个小时
            $data = array_reduce(Db::name('UserLevel')->select(),function(&$newArray,$v){$newArray[$v['level_id']] = $v;return $newArray;});
            Cache::set('user_level',$data,config('CACHE_TIME'));
        }
        
        //行为日志菜单表信息
        if(!Cache::get('menu_list')){
            //获取数据缓存2个小时
            $data = array_reduce(Db::name('Menu')->select(),function(&$newArray,$v){$newArray[$v['module'].'/'.$v['controller'].'/'.$v['action']] = $v;return $newArray;});
            Cache::set('menu_list',$data,config('CACHE_TIME'));
        }
        
        //超级管理员菜单表信息
        if(!Cache::get('admin_menu_list')){
            //获取数据缓存2个小时
            $data = model('Menu')->getMenuTree(1);
            Cache::set('admin_menu_list',$data,config('CACHE_TIME'));
        }
        
        $this->role_list = Cache::get('role_list');
        $this->user_level = Cache::get('user_level');
        $this->menu_list = Cache::get('menu_list');
        $this->admin_menu_list = Cache::get('admin_menu_list');
       
    }

    /**
     * 获取该管理员的权限
     * @param type $role_id
     * @return type
     */
    public function getPermissions ($role_id=array()) {
        $permissions_ids = array();
        foreach ($role_id as $k=>$v){
            $permissions_ids[]= Db::name('Permissions')->field('menu_ids')->where(['role_id'=>$v])->find()['menu_ids'];
        }
        
        $new_permissions_ids = implode(',',$permissions_ids);
        //查询可以访问的节点并形成菜单层次树和拼接可以访问的节点信息存在session中
        return model('Menu')->getPermissions(implode(',', array_unique(explode(',',$new_permissions_ids))));
    }
    
    /**
     * 记录行为日志
     * @param type $node
     */
    protected function actionLog ($node) {
        foreach($this->menu_list as $k => $v){
            if($k == $node){
                $action_log = array(
                    'admin_id' => Session::get('admin_info.admin_id'),
                    'action_ip' => Request::instance()->ip(),
                    'action_note' => '访问了'.$this->menu_list[$node]['menu_name'],
                    'action_url' => $node,
                    'action_time' => time(),
                    'admin_name' => Session::get('admin_info.admin_name'),
                  );
                Db::name('ActionLog')->insert($action_log);
            }
        }
    }

    

    /**
     * 组装菜单信息并抛出
     * @param type $menu_list
     */
    private function outputMenu ($menu_list) {
        $menuStr = '';        
        foreach ($menu_list as $k=>$v){
            \UtilD::sortArrByField($v['children'],'sorting'); //按照排序字段排序
            $menuStr.=<<<php
                <div class="accordion-group">
                    <div class="accordion-heading">
                        <a class="accordion-toggle b_{$k} collapsed" data-toggle="collapse" data-parent="#accordion{$k}" href="#collapse{$k}"><i class="{$v['menu_icon']}"></i> <span>{$v['menu_name']}</span></a>
                    </div>
                <div id="collapse{$k}" class="accordion-body collapse">
                    <div class="accordion-inner">
php;
            foreach ($v['children'] as $kk => $vv) {
                $url = '';
                $url = url("{$vv['module']}".'/'."{$vv['controller']}".'/'."{$vv['action']}");
                $menuStr.=<<<php
                    <a class="accordion-toggle" href="$url"><i class="{$vv['menu_icon']}"></i>{$vv['menu_name']}</a>
php;
            }
    
           $menuStr.="</div></div></div>";
        }
        $this->assign('menuStr',$menuStr);
    }
    
}